﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SdmxMl.Helper
{
    /// <summary>
    /// Helper class for managing tree nodes navigation history
    /// </summary>
    public class TreeNavigation
    {
        #region Internal Members

        private  TreeView tv;
        private  ToolStripButton butBack;
        private  ToolStripButton butFwd;
        private  ToolStripButton butParent;
        private  ToolStripComboBox comboHistory;


        private  int historySize;
        private  int currentIndex;
        private  List<object> objList;
        private  bool ownRequest;

        #endregion

        #region C'tor

        public TreeNavigation()
        {
            historySize = 10;
            objList = new List<object>(historySize);
            currentIndex = -1;
        }
        #endregion

        #region Properties

        public  TreeView TreeSdmx
        {
            set
            {
                if (tv != null)
                {
                    tv.AfterSelect -= new TreeViewEventHandler(treeView_AfterSelect);
                }

                // New one
                tv = value;
                tv.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);
            }
        }
        #endregion

        #region Treenode selection Event

        private  void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (ownRequest)
            {
                UpdatenavigationState();
                ownRequest = false;
                return;
            }
            if (e != null && e.Node != null && e.Node.Tag != null)
            {
                if (currentIndex + 1 == historySize)
                {
                    objList.RemoveAt(0);
                    objList.Add(e.Node.Tag);
                }
                else
                {
                    objList.Add(e.Node.Tag);
                    ++currentIndex;
                }

                UpdatenavigationState();
            }
        }
        #endregion

        #region Public Methods

        public void RequestNavigation(object ob)
        {
            TreeNode targetNode = null;
            if (tv != null && tv.SelectedNode != null)
            {
                TreeHelper.LocateObject(tv, ob, ref targetNode);
                if (targetNode != null)
                    tv.SelectedNode = targetNode;
            }
        }

        public void Reset()
        {
            objList.Clear();
            currentIndex = -1;
            if (tv != null && tv.SelectedNode != null && tv.SelectedNode.Tag != null)
            {
                objList.Add(tv.SelectedNode.Tag);
                currentIndex = 0;
            }

            UpdatenavigationState();
        }
        #endregion

        #region Binding Navigation buttons for History

        public  void RecordNavButtons(ToolStripButton bBack, ToolStripButton bFwd, 
            ToolStripButton bParent, ToolStripComboBox cbHistory)
        {
            // Remove previous event if any
            if (butBack != null)
                butBack.Click -= new System.EventHandler(toolStripButtonNavBack_Click);
            if (butFwd != null)
                butFwd.Click -= new System.EventHandler(toolStripButtonNavFwd_Click);
            if (butParent != null)
                butParent.Click -= new System.EventHandler(toolStripButtonNavParent_Click);
            if (comboHistory != null)
                comboHistory.SelectedIndexChanged -= new EventHandler(comboHistory_SelectedIndexChanged);

            // Update referenced buttons
            butBack = bBack;
            butFwd = bFwd;
            butParent = bParent;
            comboHistory = cbHistory;

            // Add events to manage
            butBack.Click += new System.EventHandler(toolStripButtonNavBack_Click);
            butFwd.Click += new System.EventHandler(toolStripButtonNavFwd_Click);
            butParent.Click += new System.EventHandler(toolStripButtonNavParent_Click);
            comboHistory.SelectedIndexChanged += new EventHandler(comboHistory_SelectedIndexChanged);

            // Upfate buttons state
            UpdatenavigationState();

        }
        #endregion

        #region Navigation buttons Events

        void comboHistory_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboHistory.SelectedIndex != currentIndex)
            {
                TreeNode targetNode = null;
                TreeHelper.LocateObject(tv, objList[comboHistory.SelectedIndex], ref targetNode);
                if (targetNode != null)
                {
                    currentIndex = comboHistory.SelectedIndex;
                    ownRequest = true;
                    tv.SelectedNode = targetNode;
                }
            }
        }


        private  void toolStripButtonNavBack_Click(object sender, EventArgs e)
        {
            TreeNode targetNode = null;
            if (currentIndex > 0 && tv != null && tv.SelectedNode != null)
            {
                TreeHelper.LocateObject(tv, objList[currentIndex-1], ref targetNode);
                if (targetNode != null)
                {
                    if (currentIndex >= 0)
                        --currentIndex;
                    ownRequest = true;
                    tv.SelectedNode = targetNode;
                }

            }
        }

        private  void UpdatenavigationState()
        {
            butBack.Enabled = currentIndex > 0;
            butFwd.Enabled = currentIndex + 1 < objList.Count;
            butParent.Enabled = true;
            comboHistory.Items.Clear();
            comboHistory.Items.AddRange(objList.ToArray());
            if (currentIndex >= 0 && currentIndex < comboHistory.Items.Count)
                comboHistory.SelectedIndex = currentIndex;

        }

        private  void toolStripButtonNavFwd_Click(object sender, EventArgs e)
        {
            TreeNode targetNode = null;
            if (currentIndex + 1 < objList.Count && tv != null && tv.SelectedNode != null)
            {
                TreeHelper.LocateObject(tv, objList[currentIndex+1], ref targetNode);
                if (targetNode != null)
                {
                    ++currentIndex;
                    ownRequest = true;
                    tv.SelectedNode = targetNode;
                }

            }

        }

        private  void toolStripButtonNavParent_Click(object sender, EventArgs e)
        {
            TreeNode targetNode = null;
            if (tv != null && tv.SelectedNode != null)
            {
                targetNode = TreeHelper.GetParentArtefactNode(tv.SelectedNode);
                if (targetNode == null)
                {
                    if (tv.SelectedNode.Parent != null)
                        targetNode = tv.SelectedNode.Parent;
                }
            }

            if (targetNode != null)
               tv.SelectedNode = targetNode;
        }
        #endregion
    }
}
